<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- 
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License. 
-->
<html>
<head>
    <link type="text/css" rel="stylesheet" href="https://struts.apache.org/css/default.css">
    <style type="text/css">
        .dp-highlighter {
            width:95% !important;
        }
    </style>
    <style type="text/css">
        .footer {
            background-image:      url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
            background-repeat:     repeat-x;
            background-position:   left top;
            padding-top:           4px;
            color:                 #666;
        }
    </style>
    <link href='https://struts.apache.org/highlighter/style/shCoreStruts.css' rel='stylesheet' type='text/css' />
    <link href='https://struts.apache.org/highlighter/style/shThemeStruts.css' rel='stylesheet' type='text/css' />
    <script src='https://struts.apache.org/highlighter/js/shCore.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushPlain.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushXml.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJava.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJScript.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushGroovy.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushBash.js' type='text/javascript'></script>
    <script type="text/javascript">
        SyntaxHighlighter.defaults['toolbar'] = false;
        SyntaxHighlighter.all();
    </script>
    <script type="text/javascript" language="javascript">
        var hide = null;
        var show = null;
        var children = null;

        function init() {
            /* Search form initialization */
            var form = document.forms['search'];
            if (form != null) {
                form.elements['domains'].value = location.hostname;
                form.elements['sitesearch'].value = location.hostname;
            }

            /* Children initialization */
            hide = document.getElementById('hide');
            show = document.getElementById('show');
            children = document.all != null ?
                    document.all['children'] :
                    document.getElementById('children');
            if (children != null) {
                children.style.display = 'none';
                show.style.display = 'inline';
                hide.style.display = 'none';
            }
        }

        function showChildren() {
            children.style.display = 'block';
            show.style.display = 'none';
            hide.style.display = 'inline';
        }

        function hideChildren() {
            children.style.display = 'none';
            show.style.display = 'inline';
            hide.style.display = 'none';
        }
    </script>
    <title>Tag Syntax</title>
</head>
<body onload="init()">
<table border="0" cellpadding="2" cellspacing="0" width="100%">
    <tr class="topBar">
        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a href="guides.html">Guides</a>&nbsp;&gt;&nbsp;<a href="tag-developers-guide.html">Tag Developers Guide</a>&nbsp;&gt;&nbsp;<a href="tag-syntax.html">Tag Syntax</a>
        </td>
        <td align="right" valign="middle" nowrap>
            <form name="search" action="https://www.google.com/search" method="get">
                <input type="hidden" name="ie" value="UTF-8" />
                <input type="hidden" name="oe" value="UTF-8" />
                <input type="hidden" name="domains" value="" />
                <input type="hidden" name="sitesearch" value="" />
                <input type="text" name="q" maxlength="255" value="" />
                <input type="submit" name="btnG" value="Google Search" />
            </form>
        </td>
    </tr>
</table>

<div id="PageContent">
    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
        <!-- We'll enable this once we figure out how to access (and save) the logo resource -->
        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; margin: 4px 4px 4px 10px;" border="0"-->
        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 2 Documentation</div>
        <div style="margin: 0px 10px 8px 10px"  class="pagetitle">Tag Syntax</div>

        <div class="greynavbar" align="right" style="padding: 2px 10px; margin: 0px;">
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13927">
                <img src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Edit Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13927">Edit Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">
                <img src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Browse Space"></a>
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">Browse Space</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13927">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13927">Add Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13927">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add News"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13927">Add News</a>
        </div>
    </div>

    <div class="pagecontent">
        <div class="wiki-content">
            <div id="ConfluenceContent"><p>The tags are designed to display dynamic data. To create a input field that displays the property "postalCode", we'd pass the String "postalCode" to the textfield tag.</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Creating a dynamic input field</b></div><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;s:textfield name="postalCode"/&gt;
</pre>
</div></div>
<p>If there is a "postalCode" property on the value stack, its value will be set to the input field. When the field is submitted back to the framework, the value of the control will be set back to the "postalCode" property.</p>

<p>Sometimes, we want to pass the dynamic data to a tag. For example, we might want to display a label with the input field, and we might want to obtain the label from the application's messages resources. Accordingly, the framework will parse expressions found in the tag attributes, so that we can merge dynamic data into the tag attributes at runtime. The expression escape sequence is "%{ ... }".  Any text embedded in the escape sequence is evalulated as an expression.</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Using an expression to set the label</b></div><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;s:textfield key="postalCode.label" name="postalCode"/&gt;
</pre>
</div></div>
<p>The expression language (<a shape="rect" href="ognl.html">OGNL</a>) lets us call methods and evaluate properties. The method <code>getText</code> is provided by ActionSupport, which is the base class for most Actions. Since the Action is on the stack, we can call any of its methods from an expression, including <code>getText</code>.</p>

<h2 id="TagSyntax-Non-StringAttributes">Non-String Attributes</h2>

<p>The HTTP protocol is text-based, but some tags have non-String attribute types, like <code>bool</code> or <code>int</code>. To make using non-String attributes intuitative, the framework evaulates <strong>all</strong> non-String attributes as an expression. In this case, you do not need to use the escape notation. (But, if you do anyway , the framework will just strip it off.)</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Evaluating booleans</b></div><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;s:select key="state.label" name="state" multiple="true"/&gt;
</pre>
</div></div>
<p>Since the attribute <code>multiple</code> maps to a boolean property, the framework does not interpret the value as a String. The value is evaluated as an expression and automtically converted to a boolean.</p>

<p>Since it's easy to forget which attributes are String and which are non-String, you can still use the escape notation.</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Evaluating booleans (verbose)</b></div><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;s:select key="state.label" name="state" multiple="%{true}"/&gt;
</pre>
</div></div>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Evaluating booleans (with property)</b></div><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;s:select key="state.label" name="state" multiple="allowMultiple"/&gt;
</pre>
</div></div>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Evaluating booleans (verbose with property)</b></div><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;s:select key="state.label" name="state" multiple="%{allowMultiple}"/&gt;
</pre>
</div></div>

<h2 id="TagSyntax-valueisanObject!"><code>value</code> is an Object!</h2>

<p>Most often, the <code>value</code> attribute is set automatically, since <code>name</code> attribute usually tells the framework which property to call to set the <code>value</code>. But, if there is a reason to set the <code>value</code> directly, be advised that <code><strong>value</strong></code> <strong>is an Object</strong> <strong><em>NOT</em></strong> <strong>a String</strong>.</p>

<p><img class="emoticon emoticon-warning" src="https://cwiki.apache.org/confluence/s/en_GB/5982/f2b47fb3d636c8bc9fd0b11c0ec6d0ae18646be7.1/_/images/icons/emoticons/warning.png" data-emoticon-name="warning" alt="(warning)"> Since <code>value</code> is not a String, whatever is passed to <code>value</code> is evaluated as an expression - <strong>NOT</strong> a String literal.</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Probably wrong!</b></div><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;s:textfield key="state.label" name="state" value="ca"/&gt;
</pre>
</div></div>
<p>If a <code>textfield</code> is passed the value attribute <code>"ca"</code>, the framework will look for a property named <code>getCa</code>. Generally, this is not what we mean. What we mean to do is pass a literal String. In the expression language, literals are placed within quotes</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Passing a literal value the right way</b></div><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;s:textfield key="state.label" name="state" value="%{'ca'}" /&gt;
</pre>
</div></div>
<p>Another approach would be to use the idiom <code>value="'ca'"</code>, but, in this case, using the expression notation is recommended.</p>

<p>Boiled down, the tag attributes are evaluated using three rules.</p>
<ol><li>All <em>String</em> attribute types are <em>parsed</em> for the "%{ ... }" notation.</li><li>All <em>non-String</em> attribute  types are <strong>not</strong> parsed, but evaluated directly as an expression</li><li>The exception to rule #2 is that if the <em>non-String</em> attribute uses the escape notion "%{}", the notation is ignored as redundant, and the content evaluated.</li></ol>


<div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Please remember about <em>altSyntax</em> option that can change when value is evaluated as an expression - <a shape="rect" href="alt-syntax.html">Alt Syntax</a></p></div></div>

<h2 id="TagSyntax-ExpressionLanguageNotations">Expression Language Notations</h2>

<div class="table-wrap"><table class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1" class="confluenceTd"> <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">&lt;p&gt;Username: ${user.username}&lt;/p&gt;</pre>
</div></div> </td><td colspan="1" rowspan="1" class="confluenceTd"><p> A JavaBean object in a standard context in Freemarker, Velocity, or JSTL EL (Not OGNL). </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"> <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">&lt;s:textfield name="username"/&gt;</pre>
</div></div> </td><td colspan="1" rowspan="1" class="confluenceTd"><p> A username property on the Value Stack. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"> <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">&lt;s:url id="es" action="Hello"&gt;
  &lt;s:param name="request_locale"&gt;
    es
  &lt;/s:param&gt;
&lt;/s:url&gt;
&lt;s:a href="%{es}"&gt;Espanol&lt;/s:a&gt;</pre>
</div></div> </td><td colspan="1" rowspan="1" class="confluenceTd"><p>  Another way to refer to a property placed on the Value Stack. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"> <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">&lt;s:property
  value="#session.user.username" /&gt;</pre>
</div></div> </td><td colspan="1" rowspan="1" class="confluenceTd"><p> The username property of the User object in the Session context. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"> <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">&lt;s:select
  label="FooBar" name="foo"
  list="#{'username':'trillian',
    'username':'zaphod'}" /&gt;</pre>
</div></div> </td><td colspan="1" rowspan="1" class="confluenceTd"><p>  A static Map, as in put("username","trillian"). </p></td></tr></tbody></table></div>


<h2 id="TagSyntax-Disallowedpropertynames">Disallowed property names</h2>

<p>The following names of property are disallowed:</p>
<ul><li>parameters</li><li>application</li><li>session</li><li>struts</li><li>request</li><li>servletRequest</li><li>servletResponse</li></ul>


<p>The below code will not work:</p>

<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;s:iterator value="parameters"/&gt;
</pre>
</div></div>

<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
public class MyAction {

    private String[] parameters;

    public String[] getParameters() {
        return parameters;
    }

}
</pre>
</div></div>

<h2 id="TagSyntax-Next:">Next: <a shape="rect" href="jsp.html">JSP</a></h2></div>
        </div>

        
    </div>
</div>
<div class="footer">
    Generated by CXF SiteExporter
</div>
</body>
</html>
